package com.paranoid.flashcard.view;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationSet;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.LinearInterpolator;
import android.view.animation.ScaleAnimation;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.paranoid.flashcard.R;
import com.paranoid.flashcard.dao.FlashcardDao;
import com.paranoid.flashcard.logic.FlashCardViewModel;
import com.paranoid.flashcard.logic.StudySession;
import com.paranoid.flashcard.model.Deck;

public class CardReviewActivity extends Activity {
	
    /** Called when the activity is first created. */

	Deck mDeck;
	StudySession mStudySession;

	FlashCardViewModel mActiveCard;
	private static final String TAG = CardReviewActivity.class.getName();
	LinearLayout mCardViewA;
	LinearLayout mCardViewB;
	LinearLayout mNextCardViewA;
	LinearLayout mNextCardViewB;
	ImageButton mRightButton;
	ImageButton mWrongButton;
	ImageButton mOtherSideButton;
	TextView mMasteryLevel;
	
	FlashcardDao mFlashcardDao;

	private final static int SCALE_DURATION = 100;
	private final static int ROTATE_DURATION = 400;
	private final static int ANIM_DURATION = 520;
	

    @Override
    public void onCreate(final Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        Bundle extras = getIntent().getExtras();
        long id = extras.getLong(Deck.KEY_ID);
        
        mFlashcardDao = FlashcardDao.getInstance(this);
        mDeck = mFlashcardDao.getDeckById(id); 
        mStudySession = new StudySession(mDeck, mFlashcardDao);
        
        setContentView(R.layout.practice_view);
        mCardViewA = (LinearLayout)findViewById(R.id.cardContentView);
        mCardViewB = (LinearLayout)findViewById(R.id.cardContentViewB);
        mNextCardViewA = (LinearLayout)findViewById(R.id.nextCardContentView);
        mNextCardViewB = (LinearLayout)findViewById(R.id.nextCardContentViewB);
        mMasteryLevel = (TextView)findViewById(R.id.masteryLevel);
        mMasteryLevel.setText(""+mDeck.getMasteryLevel());
        
		mActiveCard = this.mStudySession.getNext();
    	fillCardView();
    	
        mRightButton = (ImageButton)findViewById(R.id.rightAnswerButton);
        mRightButton.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		CardReviewActivity.this.rightButtonClicked();
        	}
        });

        mWrongButton = (ImageButton)findViewById(R.id.wrongAnswerButton);
        mWrongButton.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		CardReviewActivity.this.wrongButtonClicked();
        	}
        });

        mOtherSideButton = (ImageButton)findViewById(R.id.otherSideButton);
        mOtherSideButton.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		CardReviewActivity.this.otherSideButtonClicked();
        	}
        });
        
        ImageButton dashboardButton = (ImageButton)findViewById(R.id.backToDashboardButton);
        dashboardButton.setOnClickListener(new OnClickListener() {
        	public void onClick(View v) {
        		CardReviewActivity.this.finish();
        	}
        });
    }
    
    @Override
    protected void onPause() {
    	super.onPause();
    }
    
    public boolean onCreateOptionsMenu(Menu menu) {
    	getMenuInflater().inflate(R.menu.practice_menu, menu);
    	return true;
    }
    
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    	case R.id.resetMastery:
    		mDeck.resetMasteryLevels();
    		mMasteryLevel.setText("0");
    		break;
    	default:
        	Toast.makeText(this, "Not implemented yet", Toast.LENGTH_SHORT).show();
    	}
    	return true;
    }
    
    private void wrongButtonClicked() {
    	nextCard(false);
    }
    
    private void otherSideButtonClicked() {
    	flipCard();
    }

    private void rightButtonClicked() {
    	nextCard(true);
    }
    
    private void enableButtons(boolean enabled) {
    	mRightButton.setEnabled(enabled);
    	mWrongButton.setEnabled(enabled);
    	mOtherSideButton.setEnabled(enabled);
    }

    private void fillCardView() {
    	TextView tA = (TextView)mCardViewA.findViewById(R.id.card_text);
    	tA.setText(mActiveCard.getSideUp());
    	TextView tB = (TextView)mCardViewB.findViewById(R.id.card_text);
    	tB.setText(mActiveCard.getSideDown());

    	ImageView iA = (ImageView)mCardViewA.findViewById(R.id.card_image);
    	iA.setImageBitmap(mActiveCard.getImageUp());
    	ImageView iB = (ImageView)mCardViewB.findViewById(R.id.card_image);
        iB.setImageBitmap(mActiveCard.getImageDown());
}
    
    private void fillNextCardView() {
    	TextView tA = (TextView)mNextCardViewA.findViewById(R.id.card_text);
    	tA.setText(mActiveCard.getSideUp());
    	TextView tB = (TextView)mNextCardViewB.findViewById(R.id.card_text);
    	tB.setText(mActiveCard.getSideDown());
    	
    	ImageView iA = (ImageView)mNextCardViewA.findViewById(R.id.card_image);
    	iA.setImageBitmap(mActiveCard.getImageUp());
    	ImageView iB = (ImageView)mNextCardViewB.findViewById(R.id.card_image);
        iB.setImageBitmap(mActiveCard.getImageDown());
    }
    
    private void nextCard(boolean success) {
    	if (success)
    		mStudySession.righAnswerForActiveCard();
    	else
    		mStudySession.wrongAnswerForActiveCard();
		mActiveCard = this.mStudySession.getNext();
    	mMasteryLevel.setText(""+mDeck.getMasteryLevel());
    	fillNextCardView();
    	animateNextCard();
    }
    
    private void animateNextCard() {
    	enableButtons(false);
    	Animation animation = AnimationUtils.loadAnimation(this, R.anim.next_card_animation);
    	animation.setAnimationListener(new AnimationListener() {
    		public void onAnimationEnd(Animation animation) {
    			CardReviewActivity.this.finishNextAnimation();
    		}

			public void onAnimationStart(Animation animation) {}

			public void onAnimationRepeat(Animation animation) {}
    	});
    	Animation animation2 = AnimationUtils.loadAnimation(this, R.anim.next_card_back_animation);
    	mCardViewA.startAnimation(animation);
    	mNextCardViewA.startAnimation(animation2);
    	mNextCardViewA.setVisibility(View.VISIBLE);
    }
    
    private void finishNextAnimation() {
    	mCardViewA.setVisibility(View.GONE);
    	LinearLayout tmp = mCardViewA;
    	mCardViewA = mNextCardViewA;
    	mNextCardViewA = tmp;
    	tmp = mCardViewB;
    	mCardViewB = mNextCardViewB;
    	mNextCardViewB = tmp;
    	enableButtons(true);
    }
    
    private void flipCard() {
    	enableButtons(false);
    	
    	AnimationSet a = new AnimationSet(true);
    	a.setDuration(ANIM_DURATION);
    	a.setInterpolator(new LinearInterpolator());
    	a.setAnimationListener(new AnimationListener() {
			public void onAnimationEnd(Animation animation) {
				CardReviewActivity.this.endFlipCard();
			}
			public void onAnimationStart(Animation animation) {}
			public void onAnimationRepeat(Animation animation) {}
    	});
    	
    	a.addAnimation(createScaleAnimation(true));
    	a.addAnimation(creteFlipAnimation(mCardViewA, true));
    	
    	mCardViewA.startAnimation(a);
    }
    
    private void endFlipCard() {
    	View v = mCardViewB;
    	mCardViewA.setVisibility(View.GONE);
    	mCardViewB.setVisibility(View.VISIBLE);
    	mCardViewB.requestFocus();
    	
    	AnimationSet a = new AnimationSet(true);
    	a.setDuration(ANIM_DURATION);
    	a.setInterpolator(new LinearInterpolator());
    	a.setAnimationListener(new AnimationListener() {
			public void onAnimationEnd(Animation animation) {
				CardReviewActivity.this.switchCardViews();
			}
			public void onAnimationStart(Animation animation) {}
			public void onAnimationRepeat(Animation animation) {}
    	});
    	
    	a.addAnimation(createScaleAnimation(false));
    	a.addAnimation(creteFlipAnimation(mCardViewB, false));
    	
    	v.startAnimation(a);
    }
    
    private Flip3DAnimation creteFlipAnimation(View v, boolean front) {
    	final float centerX = v.getWidth() / 2f;
    	final float centerY = v.getHeight() / 2f;
    	
    	final Flip3DAnimation rotation;
    	if (front)
    		rotation = new Flip3DAnimation(0, 90, centerX, centerY);
    	else
    		rotation = new Flip3DAnimation(-90, 0, centerX, centerY);
    	rotation.setFillAfter(true);
    	rotation.setDuration(SCALE_DURATION);
    	rotation.setStartOffset(0);
    	
    	return rotation;
    }
    
    private ScaleAnimation createScaleAnimation(boolean front) {
    	final ScaleAnimation animation;
    	if (front)
    		animation = new ScaleAnimation(1f, 0.65f, 1f, 0.65f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    	else
    		animation = new ScaleAnimation(0.65f, 1f, 0.65f, 1f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    	animation.setFillAfter(false);
    	animation.setDuration(ROTATE_DURATION);
    	animation.setStartOffset(0);
    	
    	return animation;
    }
    
    
    private void switchCardViews() {
    	LinearLayout tmp = mCardViewB;
    	mCardViewB = mCardViewA;
    	mCardViewA = tmp;
    	enableButtons(true);
    }
    
}